/**
 * Copyright (c) 2020-2021 浦东大爷 All rights reserved.
 * 机会永远都是留给有准备的人
 */
package com.job.moudle2.task1;

import java.util.Random;

/**
 * @author: Scott.yu
 * @date: 2020-11-10
 * @description: 定义一个16*16的二维数组，并完成各行各列以及对角线数据的和
 */
public class DyadicArray {
    private int[][] iDyadicArray;

    private int[] sumColumn; //用于存放每一列的和
    private int[] sumRow;   // 用于存放每一行的和
    private int sumDiagonal1; // 用于存放左上到右下对角线数据的和 i==j
    private int sumDiagonal2; // 用于存放左下到右上对角线数据的和 i+j == 15

    private boolean iscompute; //用于控制是否需要重新计：false 未计算，true 已计算

    /**
     * 自定义无参构造初始化成员变量
     */
    public DyadicArray() {
        iDyadicArray = new int[16][16];
        sumColumn = new int[16];
        sumRow = new int[16];
        initArray();
    }

    /**
     * 自定义initArray方法用于随机生成100以内的数据初始化iDyadicArray数组成员
     */
    private void initArray() {
        System.out.println("\t\t系统自动生成了一个随机数100以内的16*16的二维数组，并完成初始化。");
        System.out.println("------------------------------------------------------------------------------------------");

        if(iDyadicArray != null) {
            Random r = new Random();
            for(int i = 0; i < 16; i++){
                for(int j = 0; j < 16; j++) {
                    iDyadicArray[i][j] = r.nextInt(100);
                }
            }
            System.out.println("\t\t数组初始化完成，可以进行计算操作");
            if(iscompute) {
                initSumVariable();
                iscompute = false; //方便控制是否需要重新计算
            }
        }
        else {
            System.out.println("\t\t数组初始化失败。");
        }
    }

    /**
     * get方法获取iDyadicArray的引用
     */
    public int[][] getiDyadicArray() {
        return iDyadicArray;
    }

    /**
     * 重新初始化数组并完成计算
     */
    public int[][] reInitiDyadicArray() {
        initArray();
        return iDyadicArray;
    }

    /**
     * 计算行、列、对角线数据的和并赋值给成员变量
     * 解题思路：
     *  行和列的和通过遍历数组然后对每个数据加到对应的行列对象中保存。
     *  对象线数据和分两种情况
     *      1.左上角到右下角，每个数据的数据行列下标都是相等的，比如[0][0],[1][1]……,所以判断i==j的时候进行求和
     *      2. 左下到右上角，每个数据的数据行列下标求和都是相同的，比如[0][15],[1][14]……,所以判断i+j等于15的时候进行求和
     */
    private void compute() {
        if(iDyadicArray == null || sumColumn == null || sumRow == null) {
            System.out.println("对象初始化失败");
            return;
        }
        for(int i = 0; i < 16; i++) {
            for(int j = 0; j < 16; j++) {
                //行求和
                sumRow[i] += iDyadicArray[i][j];
                //列求和
                sumColumn[j] += iDyadicArray[i][j];
                if(i == j)sumDiagonal1 += iDyadicArray[i][j];
                if((i+j) == 15)sumDiagonal2 += iDyadicArray[i][j];
            }
        }
        iscompute = true; //已经完成计算，置为true避免再次计算。
    }

    /**
     * 求和数组的数据恢复初始值
     */
    private void initSumVariable() {
        sumDiagonal1 = 0; //置为0，方便重新计算
        sumDiagonal2 = 0; //置为0，方便重新计算
        for(int i = 0; i < 16; i ++) {
            sumRow[i] = 0; //置为0，方便重新计算
            sumColumn[i] = 0; //置为0，方便重新计算

        }
    }

    /**
     * 自定义show方法打印输出结果。
     */
    public void show() {
        if(!iscompute)compute(); //打印之前判断是否已经进行计算，如果未计算则调用计算方法进行统计
        System.out.println("------------------------------------------------------------------------------------------");
        for(int i = 0; i < 16; i++){
            System.out.print("\t\t");
            for(int j = 0; j < 16; j++) {
                System.out.print(iDyadicArray[i][j] + "\t");
            }
            System.out.println("第" + i + "行的和：" + sumRow[i]);
        }
        System.out.print("列的和：\t");
        for(int i = 0; i < 16; i++){
            System.out.print(sumColumn[i] + "\t");
        }
        System.out.println("");
        System.out.println("左上角到右下角数据的和：" + sumDiagonal1 + "\t\t\t左下角到右上角对角线数据的和:" + sumDiagonal2);
        System.out.println("------------------------------------------------------------------------------------------");
    }
}
